package com.jc.platform.yanglingzhi.service.base.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jc.platform.yanglingzhi.mapper.IPartnerMapper;
import com.jc.platform.yanglingzhi.mapper.IRPartnerSalesMapper;
import com.jc.platform.yanglingzhi.mapper.ISalesContractMapper;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;




import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jc.platform.common.annotation.DataIsolation;
import com.jc.platform.common.constants.GlobalConstant;
import com.jc.platform.common.constants.StringPool;
import com.jc.platform.common.model.UserInfo;
import com.jc.platform.common.model.QueryParam;
import com.jc.platform.common.result.PageInfo;
import com.jc.platform.common.result.ResultCodeEnum;
import com.jc.platform.common.result.ResultModel;
import com.jc.platform.common.search.SqlUtils;
import com.jc.platform.common.utils.BeanUtil;
import com.jc.platform.common.utils.RequestUtil;
import com.jc.platform.yanglingzhi.vo.SalesContractVO;
import com.jc.platform.yanglingzhi.entity.SalesContractEntity;
import com.jc.platform.yanglingzhi.mapper.ISalesContractMapper;
import com.jc.platform.yanglingzhi.service.base.impl.BaseServiceImpl;
import com.jc.platform.yanglingzhi.service.base.IBaseSalesContractService;
import com.jc.platform.mybatis.utils.CollectCovertUtil;
import com.jc.platform.mybatis.utils.ConditionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import com.jc.platform.yanglingzhi.vo.SalesContractStageVO;
import com.jc.platform.yanglingzhi.service.ISalesContractStageService;
import com.jc.platform.yanglingzhi.vo.SalesContractFileInfoVO;
import com.jc.platform.yanglingzhi.service.ISalesContractFileInfoService;

import com.jc.platform.redis.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.jc.platform.common.utils.CollectionUtil;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import com.jc.platform.yanglingzhi.mapper.IRPartnerSalesMapper;
import com.jc.platform.yanglingzhi.entity.RPartnerSalesEntity;

/**
 * ClassName AbstractSalesContractServiceImpl.java
 * Description 销售合同
 *
 * @author 集团管理员
 * @date 2022/01/22
 */
@Slf4j
public abstract class AbstractSalesContractServiceImpl extends BaseServiceImpl<SalesContractVO> implements IBaseSalesContractService
{
	private static final String KEY_PREFIX = "db_platformYanglingzhi:t_salesContract";

    @Autowired
    private RedisUtils<String, SalesContractVO> redisUtils;
    @Autowired
    private ISalesContractStageService salesContractStageService;
    @Autowired
    private ISalesContractFileInfoService salesContractFileInfoService;
    @Autowired
    private IPartnerMapper partnerMapper;
    @Autowired
    private IRPartnerSalesMapper rPartnerSalesMapper;
    @Autowired
    private ISalesContractMapper salesContractMapper;






	@Override
	public ResultModel<SalesContractVO> insert(SalesContractVO salesContractVO)
	{
		SalesContractEntity entity = new SalesContractEntity();
		entity.copyFormVO(salesContractVO);
		salesContractMapper.insert(entity);

            SalesContractFileInfoVO salesContractFileInfo = salesContractVO.getSalesContractFileInfo();
            if (salesContractFileInfo != null) {
               salesContractFileInfo.setSalesContractId(entity.getId());
                salesContractFileInfoService.insert(salesContractFileInfo);
            }
		salesContractVO.setId(entity.getId());
		delRedisKeyBatch(KEY_PREFIX);
		return ResultModel.success(salesContractVO);
	}

	@Override
	public ResultModel<SalesContractVO> update(SalesContractVO salesContract)
	{
		SalesContractEntity entity = new SalesContractEntity();
		entity.copyFormVO(salesContract);
		salesContractMapper.updateById(entity);
         //删除前台选中删除的集合数据
        List<SalesContractStageVO> delSalesContractStageList = salesContract.getSalesContractStageList();
        if (CollectionUtil.isNotEmpty(delSalesContractStageList)) {
            List<Long> delSalesContractStageIdList = delSalesContractStageList.stream().map(SalesContractStageVO::getId).filter(Objects::nonNull).collect(Collectors.toList());
            salesContractStageService.deleteBatch(delSalesContractStageIdList);
        }
        List<SalesContractStageVO> salesContractStageList = salesContract.getSalesContractStageList();
        if(CollectionUtil.isNotEmpty(salesContractStageList)){
            salesContractStageList.forEach(item->{
                if (item.getId() == null) {
                            item.setSalesContractId(salesContract.getId());
                    salesContractStageService.insert(item);
                } else {
                    salesContractStageService.update(item);
                }
            });
        }


        SalesContractFileInfoVO salesContractFileInfo = salesContract.getSalesContractFileInfo();
            if (salesContractFileInfo != null) {
         SalesContractFileInfoVO sourceSalesContractId = salesContractFileInfoService.getBySalesContractIdExtend(entity.getId());
         salesContractFileInfo.setSalesContractId(entity.getId());
        if (sourceSalesContractId != null) {
            salesContractFileInfo.setId(sourceSalesContractId.getId());
            salesContractFileInfoService.update(salesContractFileInfo);
        } else {
            salesContractFileInfoService.insert(salesContractFileInfo);
        }
            }

		salesContract.setId(entity.getId());
		delRedisKeyBatch(KEY_PREFIX);
        delFromRedisAsync(entity.getId());
		entity = salesContractMapper.selectById(entity.getId());
		return ResultModel.success(entity.copyToVO());
	}


    @Override
	public ResultModel<Boolean> delete(Long id)
	{
                        salesContractFileInfoService.delBySalesContractId(id);
        
         int count = salesContractMapper.deleteById(id);

		if (count > 0)
		{
			delRedisKeyBatch(KEY_PREFIX);
            delFromRedisAsync(id);
			return ResultModel.success(true);
		}
		else
		{
			return ResultModel.success(false);
		}
	}

    @Override
	public ResultModel<Boolean> deleteBatch(List<Long> ids)
	{
        if (CollectionUtil.isEmpty(ids)) {
			return ResultModel.success(true);
		}

        ids.forEach(x -> {
            salesContractFileInfoService.delBySalesContractId(x);
        });              
        ids.forEach(id -> {
            salesContractMapper.deleteById(id);
        });

        delRedisKeyBatch(KEY_PREFIX);
        return ResultModel.success(true);
	}




	@Override
	public Boolean checkNotExists(Long id, String property, String value)
	{
        QueryWrapper<SalesContractEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(BeanUtil.newInstance(SalesContractEntity.class));
        queryWrapper.eq(SqlUtils.getColumnByProperty(property), value);

        if(id!=null && id>0){
            queryWrapper.ne(StringPool.ID, id);
        }


        return salesContractMapper.selectCount(queryWrapper) <= 0;
	}

	@Override
	public ResultModel<SalesContractVO> get(Long id)
	{
        String redisKey = RedisUtils.getRedisKey(KEY_PREFIX, id);
        SalesContractVO salesContractVO = getRedis(redisKey);
        if (salesContractVO == null)
        {
            SalesContractEntity entity = salesContractMapper.selectById(id);
            if (entity == null){
                return ResultModel.failed();
            }
            salesContractVO = entity.copyToVO();

            salesContractVO.setPartnerPOList(CollectCovertUtil.listVO(partnerMapper.findBySalesContract(id)));
            salesContractVO.setSalesContractFileInfo(salesContractFileInfoService.getBySalesContractIdExtend(salesContractVO.getId()));
            salesContractVO.setSalesContractStageList(salesContractStageService.findBySalesContractIdChildren(salesContractVO.getId()));



            setRedis(redisKey, salesContractVO);
        }
        return ResultModel.success(salesContractVO);
	}

	@Override
	@DataIsolation(value = {"group_id","org_id","dept_id","create_id"})
	public ResultModel<List<SalesContractVO>> find(QueryParam queryParam)
	{
		UserInfo userInfo = RequestUtil.getLoginUser();
		queryParam.getQuery().put("group_id",userInfo.getGroupId());
        String redisKey = RedisUtils.getRedisKey(KEY_PREFIX, "collection:find." + queryParam.toString());
        List<SalesContractVO> list = getRedisForList(redisKey);
            if (list == null || list.isEmpty())
            {
                if (queryParam.getQuery().get("group_id") != null) {
                    queryParam.getQuery().put("sales_contract.group_id", queryParam.getQuery().get("group_id"));
                    queryParam.getQuery().remove("group_id");
                }
                if (queryParam.getQuery().get("org_id") != null) {
                    queryParam.getQuery().put("sales_contract.org_id", queryParam.getQuery().get("org_id"));
                    queryParam.getQuery().remove("org_id");
                }
                if (queryParam.getQuery().get("dept_id") != null) {
                    queryParam.getQuery().put("sales_contract.dept_id", queryParam.getQuery().get("dept_id"));
                    queryParam.getQuery().remove("dept_id");
                }
                QueryWrapper<SalesContractVO> queryWrapper = ConditionUtil.getQueryWrapper(queryParam, SalesContractVO.class);
                list = salesContractMapper.findExtend(queryWrapper);

                if (list != null && !list.isEmpty())
                {
                    setRedis(redisKey,list);
                }
            }
        return ResultModel.success(list);
	}

	@Override
	@DataIsolation(value = {"group_id","org_id","dept_id","create_id"})
	public ResultModel<PageInfo<SalesContractVO>> finds(QueryParam queryParam)
	{
		UserInfo userInfo = RequestUtil.getLoginUser();
		queryParam.getQuery().put("group_id",userInfo.getGroupId());

        String redisKey = RedisUtils.getRedisKey(KEY_PREFIX, "collection:finds." + queryParam.toString());
        PageInfo<SalesContractVO> page = getRedisForPage(redisKey);
        if (page == null)
        {
            if (queryParam.getQuery().get("group_id") != null) {
                queryParam.getQuery().put("sales_contract.group_id", queryParam.getQuery().get("group_id"));
                queryParam.getQuery().remove("group_id");
            }
            if (queryParam.getQuery().get("org_id") != null) {
                queryParam.getQuery().put("sales_contract.org_id", queryParam.getQuery().get("org_id"));
                queryParam.getQuery().remove("org_id");
            }
            if (queryParam.getQuery().get("dept_id") != null) {
                queryParam.getQuery().put("sales_contract.dept_id", queryParam.getQuery().get("dept_id"));
                queryParam.getQuery().remove("dept_id");
            }
            QueryWrapper<SalesContractVO> queryWrapper = ConditionUtil.getQueryWrapper(queryParam, SalesContractVO.class);
            IPage<SalesContractVO> iPage = salesContractMapper.findExtends(ConditionUtil.getPage(queryParam), queryWrapper);
            page = new PageInfo<>();
            page.setList(iPage.getRecords());
            page.setPageNum(queryParam.getPageNum());
            page.setPageSize(queryParam.getPageSize());
            page.setTotal(iPage.getTotal());
            setRedis(redisKey,page);
        }
        return ResultModel.success(page);

	}

    @Override
	public ResultModel<Integer> count(QueryParam queryParam)
	{
        QueryWrapper<SalesContractEntity> queryWrapper = ConditionUtil.getQueryWrapper(queryParam, SalesContractEntity.class);
        Integer count = salesContractMapper.selectCount(queryWrapper);
		return ResultModel.success(count);
	}



    /**
     * 执行【合作单位】添加
     *
     * @param id
     * @param partnerId
     * @return
     */
    private int doAddPartner(Long id, Long... partnerId) {
        int count = 0;
        for (Long _id : partnerId) {
            if(partnerMapper.selectById(_id) != null){
                count += salesContractMapper.addPartner(id, _id);
            }
        }
        return count;
    }

    /**
     * 设置【合作单位】
     *
     * @param id
     * @param partnerId
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public int setPartner(Long id, Long[] partnerId) {
        salesContractMapper.removeAllPartner(id);
        delFromRedisAsync(id);
        if(ArrayUtils.isEmpty(partnerId)){
            return 0;
        }
        return doAddPartner(id, partnerId);
    }





    private void delFromRedisAsync(Object id)
	{
        redisUtils.del(RedisUtils.getRedisKey(KEY_PREFIX, id));
	}

	private void delColRedis()
	{
		String keyPattern = RedisUtils.getRedisKey(KEY_PREFIX, "collection:*");
		Set<String> keys = redisUtils.keys(keyPattern);
		if (keys != null)
		{
			String[] keyArray = keys.toArray(new String[] {});
			redisUtils.del(keyArray);
		}
	}
}

